﻿using System;
using System.Reflection;
using System.Text;
using System.Reflection.Emit;

namespace msilgc.cbuilder.MSILSyntaxTree
{
    internal class Instruction {
        public Instruction(int offset, OpCode code, byte[] data) {
            Offset = offset;
            Inst = code;
            Data = data;
        }

        public readonly int Offset;
        public readonly OpCode Inst;
        public readonly byte[] Data;

        public FieldInfo FieldOperand { get; set; }
        public MethodBase MethodOperand { get; set; }
        public MemberInfo MemberOperand { get; set; }
        public Type InlineType { get; set; }
        public string InlineString { get; set; }
        public int[] SwitchOffsets { get; set; }
        public IBasicBlock[] SwitchTargets { get; set; }

        public override string ToString() {
            StringBuilder builder = new StringBuilder(32);
            builder.Append("0x");
            builder.Append(Offset.ToString("x2"));
            builder.Append(": ");
            builder.Append(Inst.Name + " ");
            if (FieldOperand == null && MemberOperand == null && MethodOperand == null && InlineType == null && Data != null && Data.Length > 0) {
                builder.Append("0x");
                foreach (byte b in Data) {
                    builder.Append(b.ToString("x2"));
                }
            }
            if(FieldOperand != null)
            {
                builder.Append(" Field: [");
                builder.Append(FieldOperand.Name);
                builder.Append("]");
            }
            if(MemberOperand != null)
            {
                builder.Append(" Member: [");
                builder.Append(MemberOperand.Name);
                builder.Append("]");
            }
            if(MethodOperand != null)
            {
                builder.Append(" Method: [");
                builder.Append(MethodOperand.Name);
                builder.Append("]");
            }
            if(InlineType != null)
            {
                builder.Append(" InlineType: [");
                builder.Append(InlineType.Name);
                builder.Append("]");
            }
            return builder.ToString();
        }

    }
}